Imports System.Drawing.Drawing2D
Module Regioning
    Public Function BitmapToRegion(ByVal bitmap As Bitmap, ByVal transparencyColor As Color, Optional ByVal Variance As Integer = 0) As Region

        If bitmap Is Nothing Then
            Throw New ArgumentNullException("Bitmap", "Bitmap cannot be Nothing!")
        End If

        Dim height As Integer = bitmap.Height
        Dim width As Integer = bitmap.Width

        Dim path As New GraphicsPath

        Dim i As Integer
        Dim j As Integer

        For j = 0 To (height - 1)
            For i = 0 To (width - 1)
                If Not bitmap.GetPixel(i, j).Equals(transparencyColor) Then
                    Dim x0 As Integer = i
                    Do While ((i < width) AndAlso (Not bitmap.GetPixel(i, j).Equals(transparencyColor)))
                        i += 1
                    Loop
                    path.AddRectangle(New Rectangle(x0, j, i - x0, 1))

                End If

            Next
        Next

        Dim region As New Region(path)
        path.Dispose()

        Return region

    End Function

    Public Function BitmapToRegion(ByVal skinBmp As Bitmap, ByVal Variance As Integer) As Region

        If skinBmp Is Nothing Then Return Nothing

        'Make a windows "region" based on a given bitmap.  It runs through the entire
        'bitmap, creating line regions from sequences of non-transparent pixels.  Each line
        'region is added to the full region.  The top-left pixel is used as the transparent color.

        Dim fullRegion As Region = Nothing
        Dim lineRegion As New Region
        Dim transparentColor As Color
        Dim inLine As Boolean = False  'Indicates if current pixel is in non-transparent run
        Dim startLineX As Integer = 0

        'Use the top-left pixel as the transparent color
        transparentColor = skinBmp.GetPixel(0, 0)

        For y As Integer = 0 To skinBmp.Height - 1
            For x As Integer = 0 To skinBmp.Width - 1

                ' If Math.Abs(skinBmp.GetPixel(x, y).ToArgb - transparentColor.ToArgb) < Variance Then
                If skinBmp.GetPixel(x, y).GetBrightness > 0.97 Then
                    'We reached a transparent pixel
                    If inLine Then
                        inLine = False
                        lineRegion = New Region(New Rectangle(startLineX, y, x - startLineX, 1))

                        If fullRegion Is Nothing Then
                            fullRegion = lineRegion
                        Else
                            fullRegion.Union(lineRegion)
                        End If
                    End If
                Else
                    'We reached a non-transparent pixel
                    If Not inLine Then
                        inLine = True
                        startLineX = x
                    End If
                End If
            Next
        Next

        Return fullRegion
    End Function
End Module
